package services

import (
	"GOPAAS/internal/app/model"
	"GOPAAS/internal/utils"
	"strconv"
	"strings"
)

type ProductionService struct {
	model.MrpProduction
}

func GetProductionService(pid int64) *ProductionService {
	db = getDB()
	var production model.MrpProduction
	if pid > 0 {
		db.First(&production, pid)
	}
	return &ProductionService{production}
}

// GetInfo 工单详情
func (p *ProductionService) GetInfo() (result ProductionItem, err error) {
	var data model.MrpProduction
	query := db.Model(&model.MrpProduction{})
	query.Preload("MrpWorkorders").Preload("User").Preload("MrpWorkorders.Workcenter").Preload("User.Partner").Preload("Company").Preload("Product").Preload("Product.ProductTmpl")
	query.Preload("StockMoves").Preload("StockMoves.Product").Preload("StockMoves.Product.ProductTmpl").Preload("StockMoves.StockMoveLines")
	res := query.First(&data, p.Id)
	if res.Error != nil {
		err = res.Error
		return
	}
	var DurationExpected float64
	var Duration float64
	var Orders = make([]WorkOrder, 0)
	var Moves = make([]StockMove, 0)
	for _, vv := range data.MrpWorkorders {
		DurationExpected += vv.DurationExpected
		Duration += vv.Duration
		Orders = append(Orders, WorkOrder{
			Id:                  vv.Id,
			Name:                vv.Name,
			ModelName:           "mrp.workorder",
			State:               vv.State,
			WorkCenter:          vv.Workcenter.Name,
			TotalNum:            data.ProductQty,
			CompleteNum:         vv.QtyProduced,
			DurationExpected:    vv.DurationExpected,
			Duration:            vv.Duration,
			DatePlannedStart:    utils.NullTimeValueFormat(vv.DatePlannedStart, "2006-01-02 15:04:05"),
			DatePlannedFinished: utils.NullTimeValueFormat(vv.DatePlannedFinished, "2006-01-02 15:04:05"),
			DateStart:           utils.NullTimeValueFormat(vv.DateStart, "2006-01-02 15:04:05"),
			DateFinished:        utils.NullTimeValueFormat(vv.DateFinished, "2006-01-02 15:04:05"),
		})
	}
	for _, vv := range data.StockMoves {
		var qty_done float64
		for _, vvv := range vv.StockMoveLines {
			qty_done += vvv.QtyDone
		}
		Moves = append(Moves, StockMove{
			Id:                   vv.Id,
			Name:                 vv.Name,
			ModelName:            "stock.move",
			ProductId:            vv.ProductId,
			ProductName:          vv.Product.ProductTmpl.Name,
			ProductUomQty:        vv.ProductUomQty,
			ForecastAvailability: 1.00,
			QuantityDone:         qty_done,
		})
	}
	result.Id = data.Id
	result.Name = data.Name
	result.ModelName = "mrp.production"
	result.State = data.State
	result.UserName = data.User.Partner.Name
	result.UserId = data.UserId.Int64
	result.BomId = data.BomId
	result.CompanyName = data.Company.Name
	result.CompanyId = data.CompanyId
	result.ProductId = data.ProductId
	result.ProductName = data.Product.ProductTmpl.Name
	result.DatePlannedStart = utils.NullTimeValueFormat(data.DatePlannedStart, "2006-01-02 15:04:05")
	result.DatePlannedFinished = utils.NullTimeValueFormat(data.DatePlannedFinished, "2006-01-02 15:04:05")
	result.DateStart = utils.NullTimeValueFormat(data.DateStart, "2006-01-02 15:04:05")
	result.DateFinished = utils.NullTimeValueFormat(data.DateFinished, "2006-01-02 15:04:05")
	//result.Specification = data.Product.Specification
	result.TotalNum = data.ProductQty
	result.CompleteNum = data.QtyProducing
	result.DurationExpected = DurationExpected
	result.Duration = Duration
	result.WorkOrder = Orders
	result.StockMove = Moves
	//订单信息
	ref_id := data.RefId
	if ref_id != "" {
		ref_arr := strings.Split(ref_id, ",")
		if len(ref_arr) >= 2 {
			orderLineId_str := ref_arr[1]
			orderLineId, _ := strconv.Atoi(orderLineId_str)
			var orderLine model.SaleOrderLine
			db.Preload("Order").Preload("Order.Partner").First(&orderLine, orderLineId)
			result.Customer = orderLine.Order.Partner.Name
			result.OrderNum = orderLine.Order.Name
			result.CommitmentDate = utils.NullTimeValueFormat(orderLine.Order.CommitmentDate, "2006-01-02 15:04:05")
		}
	}
	return
}

// WorkOrder 工序
type WorkOrder struct {
	Id                  int64   `json:"id"`
	Name                string  `json:"name"`
	State               string  `json:"state"`
	ModelName           string  `json:"model_name"`
	TotalNum            float64 `json:"total_num"`             //总数
	WorkCenter          string  `json:"work_center"`           //工作中心
	CompleteNum         float64 `json:"complete_num"`          //完成数量
	DurationExpected    float64 `json:"duration_expected"`     //预计时长
	Duration            float64 `json:"duration"`              //实际时长
	DatePlannedStart    string  `json:"date_planned_start"`    //预期开始时间
	DatePlannedFinished string  `json:"date_planned_finished"` //预期完成时间
	DateStart           string  `json:"date_start"`            //实际开始时间
	DateFinished        string  `json:"date_finished"`         //实际完成时间
}

// StockMove 组件
type StockMove struct {
	Id                   int64   `json:"id"`
	Name                 string  `json:"name"`
	ModelName            string  `json:"model_name"`
	ProductId            int64   `json:"product_id"`
	ProductName          string  `json:"product_name"`
	ProductUomQty        float64 `json:"product_uom_qty"`       //待消耗
	ForecastAvailability float64 `json:"forecast_availability"` //已预留
	QuantityDone         float64 `json:"quantity_done"`         //已消耗
}

type ProductionItem struct {
	Id                  int64       `json:"id"`
	Name                string      `json:"name"`
	ModelName           string      `json:"model_name"`
	State               string      `json:"state"`
	UserName            string      `json:"user_name"`
	UserId              int64       `json:"user_id"`
	BomId               int64       `json:"bom_id"`                //物料清单
	CompanyName         string      `json:"company_name"`          //公司
	CompanyId           int64       `json:"company_id"`            //公司
	ProductId           int64       `json:"product_id"`            //产品
	ProductName         string      `json:"product_name"`          //产品
	DatePlannedStart    string      `json:"date_planned_start"`    //预期开始时间
	DatePlannedFinished string      `json:"date_planned_finished"` //预期完成时间
	DateStart           string      `json:"date_start"`            //实际开始时间
	DateFinished        string      `json:"date_finished"`         //实际完成时间
	Specification       string      `json:"specification"`         //规格
	TotalNum            float64     `json:"total_num"`             //总数
	CompleteNum         float64     `json:"complete_num"`          //已完成数量
	DurationExpected    float64     `json:"duration_expected"`     //预计时长(分钟)
	Duration            float64     `json:"duration"`              //实际时长(分钟)
	Customer            string      `json:"customer"`              //客户
	OrderNum            string      `json:"order_num"`             //订单号
	CommitmentDate      string      `json:"commitment_date"`       //交货日期
	WorkOrder           []WorkOrder `json:"work_order"`
	StockMove           []StockMove `json:"stock_move"` //组件
}

// ProductionLists 工单管理
func ProductionLists(company_id int64, search string, state []string, user_id int64, page int, limit int) (data []ProductionItem, err error) {
	db = getDB()
	data = make([]ProductionItem, 0)
	var offset int
	offset = (page - 1) * limit
	var productions []model.MrpProduction
	q := db.Model(&model.MrpProduction{}).Joins("left join product_product on mrp_production.product_id=product_product.id").Joins("join product_template on product_product.product_tmpl_id=product_template.id and product_template.active=true")
	if company_id > 0 {
		q.Where("mrp_production.company_id=?", company_id)
	}
	if len(state) > 0 {
		q.Where("mrp_production.state in ?", state)
	}
	if user_id > 0 {
		q.Where("mrp_production.user_id =?", user_id)
	}
	if len(search) > 0 {
		q.Where("(mrp_production.name like ? or product_template.name like ?)", "%"+search+"%", "%"+search+"%")
	}
	err = q.Preload("MrpWorkorders").Preload("User").Preload("User.Partner").Preload("Company").Preload("Product").Preload("Product.ProductTmpl").Offset(offset).Limit(limit).Order("date_planned_start desc,id desc").Find(&productions).Error
	for _, v := range productions {
		var DurationExpected float64
		var Duration float64
		var Orders = make([]WorkOrder, 0)
		for _, vv := range v.MrpWorkorders {
			DurationExpected += vv.DurationExpected
			Duration += vv.Duration
			Orders = append(Orders, WorkOrder{
				Id:               vv.Id,
				ModelName:        "mrp.workorder",
				TotalNum:         v.ProductQty,
				CompleteNum:      vv.QtyProduced,
				DurationExpected: vv.DurationExpected,
				Duration:         vv.Duration,
			})
		}
		data = append(data, ProductionItem{
			Id:                  v.Id,
			Name:                v.Name,
			ModelName:           "mrp.production",
			State:               v.State,
			UserName:            v.User.Partner.Name,
			UserId:              v.UserId.Int64,
			CompanyName:         v.Company.Name,
			CompanyId:           v.CompanyId,
			DatePlannedStart:    utils.NullTimeValueFormat(v.DatePlannedStart, "2006-01-02 15:04:05"),
			DatePlannedFinished: utils.NullTimeValueFormat(v.DatePlannedFinished, "2006-01-02 15:04:05"),
			DateStart:           utils.NullTimeValueFormat(v.DateStart, "2006-01-02 15:04:05"),
			DateFinished:        utils.NullTimeValueFormat(v.DateFinished, "2006-01-02 15:04:05"),
			//Specification:       v.Product.Specification,
			ProductName:      v.Product.ProductTmpl.Name,
			TotalNum:         v.ProductQty,
			CompleteNum:      v.QtyProducing,
			DurationExpected: DurationExpected,
			Duration:         Duration,
			WorkOrder:        Orders,
		})
	}
	return
}
